{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Kotlin Technology Sharing\n",
    "\n",
    "\n",
    "\n",
    " **Author  :   蔡海飞  **  \n",
    " **Date      :    2018/1/XX**\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Introduration\n",
    "\n",
    "- 时间线\n",
    "- Koltin的使用场景\n",
    "- 为什么使用kotlin ?\n",
    "- Kotlin与Java\n",
    "- Kotlin的特性\n",
    "- Kotlin 检索"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## 时间线\n",
    "\n",
    "- July 18,2011  \n",
    "  Kotlin 于2011年7月18日在Jvm language Commit 会议中被JetBrains公布\n",
    "\n",
    "- August 3, 2011  \n",
    "   JetBrains 公布Kotlin 事件跟踪器\n",
    "   \n",
    "- January 10,2012  \n",
    "  Kotlin公开预览版\n",
    "  \n",
    "- February 14,2012  \n",
    "   Kotlin 开放源代码( http://github.com/JetBrains/Kotlin)\n",
    " \n",
    "- October 10,2012 \n",
    "   Kotlin 网络研讨会\n",
    "   \n",
    "- December 11,2012  \n",
    "   kotlin M4完成\n",
    "   \n",
    "- August 12,2013  \n",
    "   Android studio支持kotlin插件\n",
    "   \n",
    "  \n",
    "- May 18,2017  \n",
    "  Google IO宣布kotlin为android开发官方语言,并且Android studio 3开始内嵌kotlin支持.\n",
    "  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Kotlin 的使用场景\n",
    "\n",
    "-  服务器端开发             \n",
    "- Android端开发   \n",
    "- 浏览器端开发               \n",
    "- 原生开发             \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "##  为什么使用kotlin ?\n",
    "\n",
    "-  **代码简洁**  \n",
    "    Kotlin的代码结构简单，支持lambda表达式，语法结构更加通俗易读.\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "\n",
    "#### POJO的实现\n",
    "```java\n",
    "//java的实现\n",
    "public class  UserInfo{\n",
    "    private String name;\n",
    "    private String pwd;\n",
    "    pulblic void setName(String name){\n",
    "        this.name=name;\n",
    "    }\n",
    "    public String getName(){\n",
    "        return name;\n",
    "    }\n",
    "    public void setPwd(String pwd){\n",
    "        this.pwd=pwd;\n",
    "    }\n",
    "    public String getPwd(){\n",
    "        return pwd;\n",
    "    }\n",
    "    ......\n",
    "}\n",
    "\n",
    "```\n",
    "```kotlin\n",
    "//kotlin的实现\n",
    "data class UserInfo(var name:String,var pwd:String)\n",
    "```\n",
    "#### 单例模式\n",
    "```kotlin\n",
    "//关键字object 可创建一个单例模式的类，可以直接使用Singleton调用，无构造函数.\n",
    "object Singleton {\n",
    "      val tag: String = \"single\"\n",
    "}\n",
    "\n",
    "```\n",
    "#### 对象创建\n",
    "```kotlin\n",
    "//创建一个String对象\n",
    "val str = \"this is a string .\"\n",
    "//创建一个int对象\n",
    "val number = 100\n",
    "//创建一个list\n",
    "val list = mutableListOf<String>()\n",
    "\n",
    "\n",
    "```\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "- **安全性**   \n",
    "   kotlin中会对变量方法进行非空检测，在编译期就避免烦人的NullPointerException错误，为此kotlin中引入了两个特殊操作符号('?'和‘!!’)。而且会对kotlin进行自动类型转换，防止因为强制转换导致的类型一场。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "```kotlin\n",
    "var output: String       //定义单个类型在对其进行赋值操作的时候会对其进行非空检测，若为空则编译错误\n",
    "output = null   // 编译错误\n",
    "\n",
    "val name: String? = null    // 可空类型，可以通过在类型后面添加一个“？”来指定该类型可以为空\n",
    "println(name.length())      // 编译错误\n",
    "\n",
    "//闯入参数要求为String类型(非空类型)\n",
    "fun test(String:args){\n",
    "     println(args)\n",
    "}\n",
    "\n",
    "test(args!!) //可以通过在参数后添加!!来强制制定传入参数，若参数为空则抛出异常\n",
    "\n",
    "if (obj is Invoice)            //kotlin 中可以通过is来判断对象的类型，若类型判断通过，kotlin会自动将该对象转化为对应类型.\n",
    "        obj.calculateTotal()\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "- ** 互操作性**  \n",
    "   kotlin也是基于Jvm的一种语言，kotlin支持给予JVM的任意语言开发的资源库的调用，即class级别通用."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "- ** 工具友好 **  \n",
    "   由于JetBrains本身就是做工具的，java级别的工具更是强大，目前支持kotlin插件的开发工具有jetBrains系列java IDE，Android Studio、Eclipse等.都是较为主流的开发工具,所以Kotlin开发的外部环境还是不错的."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "##  Kotlin与Java\n",
    "\n",
    "- 语法简单，易懂  \n",
    "  Kotlin中对于语法的设计更加类似于python这类的脚本语言的语法格式\n",
    "  \n",
    "  \n",
    "- 空指针安全和类型的自动转换\n",
    " 如上安全性的定义, kotlin需要对类型进行空指针校验，相对于java中比较烦人的空指针异常让人舒服很多\n",
    "  \n",
    "  \n",
    "- 支持方法和属性的扩展  \n",
    "  kotlin的方法扩展的特性可以说是一大亮点,我们可以直接针对类进行方法扩展，而不需要在特意定制某个自定义类来进行定制.\n",
    "  \n",
    "\n",
    "- lambda，高阶函数,协程，数据类(data class),inline函数等\n",
    "  kotlin特有特性，使得kotlin的使用更加的方便和简单，会在之后对部分特性进行介绍.\n",
    "\n",
    "\n",
    "- 不得不说的android findViewById()  \n",
    "  kotlin对于android findViewById的精简可谓是相当高效的，允许直接通过id名来代替控件本身.\n",
    "\n",
    "\n",
    "- kotlin于java的互操作性  \n",
    "  和java 一样kotlin也同属于jvm语言，两者直接可以通过编译成class文件直接互相调用.\n",
    "  \n",
    " \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Kotlin的特性\n",
    "\n",
    "- **空安全**   \n",
    "   **Kotlin 的类型系统旨在消除来自代码空引用的危险，也称为Tony Hoare的《十亿美元的错误》**。许多编程语言（包括 Java）中最常见的陷阱之一是访问空引用的成员，导致空引用异常。在 Java 中， 这等同于 NullPointerException 或简称 NPE。\n",
    "    Kotlin 的类型系统旨在从我们的代码中消除 NullPointerException。NPE 的唯一可能的原因可能是：\n",
    "     - 显式调用 throw NullPointerException()\n",
    "     - 使用了 !! 操作符\n",
    "     - 外部 Java 代码导致的\n",
    "     - 对于初始化，有一些数据不一致（如一个未初始化的 this 用于构造函数的某个地方）\n",
    "     在 Kotlin 中，类型系统区分一个引用可以容纳 null （可空引用）还是不能容纳（非空引用）。 例如，String 类型的常规变量不能容纳 null：\n",
    "```kotlin\n",
    "var a: String = \"abc\"\n",
    "a = null // 编译错误\n",
    "```\n",
    "如果要允许为空，我们可以声明一个变量为可空字符串，写作 String?：\n",
    "```kotlin\n",
    "var b: String? = \"abc\"\n",
    "b = null // ok\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "\n",
    "- **DTOS(POJOs/POCOs) **  \n",
    "  java中的pojo,会为类的对象提供getter(),equals()、hashCode()、toString()，copy()等方法，简化了创建方式：\n",
    "  \n",
    "  ```kotlin\n",
    "\n",
    " //若为var类型还会提供setter方法\n",
    "  data class Customer(val name: String, val email: String)\n",
    "  ```\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "- **扩展**  \n",
    "  Kotlin能够扩展一个类的新功能而无需继承该类或使用像装饰者这样的任何类型的设计模式。 这通过叫做 扩展 的特殊声明完成。Kotlin 支持 扩展函数 和 扩展属性。\n",
    "  ##### 扩展函数\n",
    "  声明一个扩展函数，我们需要用一个 接收者类型 也就是被扩展的类型来作为他的前缀。 下面代码为 MutableList<Int> 添加一个swap 函数：\n",
    "    ```kotlin\n",
    "    fun Context.toast(String msg) {\n",
    "       Toast.makeText(this,msg,Toast.LENGTH_SHORT).show()\n",
    "     }\n",
    "\n",
    "   ```\n",
    "  这个 this 关键字在扩展函数内部对应到接收者对象,通过如上操作就可以直接在Context的子类中调用toast方法了.\n",
    "  \n",
    "  ##### 扩展属性\n",
    "  ```kotlin\n",
    "   val <T> List<T>.lastIndex: Int\n",
    "             get() = size - 1\n",
    "\n",
    "  ```\n",
    "   注意：由于扩展没有实际的将成员插入类中，因此对扩展属性来说幕后字段是无效的。这就是为什么扩展属性不能有初始化器。他们的行为只能由显式提供的 getters/setters 定义。\n",
    "  \n",
    "  \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "- **内联函数(inline)、高阶函数和lambda表达式**  \n",
    "\n",
    "1.高阶函数  \n",
    "\n",
    "高阶函数是将函数用作参数或返回值的函数，如下:\n",
    "      \n",
    " ```kotlin\n",
    "         fun <T> lock(lock: Lock, body: () -> T): T {\n",
    "              lock.lock()\n",
    "              try {\n",
    "                 return body()\n",
    "               }\n",
    "              finally {\n",
    "                lock.unlock()\n",
    "            }\n",
    "       }\n",
    " \n",
    " ```\n",
    "2.内联函数  \n",
    "使用高阶函数会带来一些运行时的效率损失：每一个函数都是一个对象，并且会捕获一个闭包。 即那些在函数体内会访问到的变量。 内存分配（对于函数对象和类）和虚拟调用会引入运行时间开销。\n",
    "```kotlin\n",
    "\n",
    "           inline fun <T> lock(lock: Lock, body: () -> T): T {\n",
    "                  // ……\n",
    "           }\n",
    "\n",
    "```   \n",
    "        inline 修饰符影响函数本身和传给它的 lambda 表达式：所有这些都将内联到调用处，编译器可以直接产生下面的代码, 而不必为参数创建函数对象, 然后再调用这个参数指向的函数:\n",
    "        \n",
    "```kotlin\n",
    "\n",
    "            l.lock()\n",
    "           try {\n",
    "               foo()\n",
    "            }\n",
    "           finally {\n",
    "               l.unlock()\n",
    "            }\n",
    "\n",
    "```\n",
    "3.lambda表达式  \n",
    "\n",
    "- 在 Kotlin 中有一个约定，如果函数的最后一个参数是一个函数，并且你传递一个 lambda 表达式作为相应的参数，你可以在圆括号之外指定它\n",
    "- 另一个有用的约定是，如果函数字面值只有一个参数， 那么它的声明可以省略（连同 ->），其名称是 it。\n",
    "- 下划线用于未使用的变量（自 1.1 起）\n",
    "- it：单个参数的隐式名称\n",
    "```kotlin\n",
    "            val result = lock(lock, { sharedResource.operation() })      //lambda 表达式\n",
    "            val result = lock (lock) {\n",
    "                            sharedResource.operation()\n",
    "            }\n",
    "```\n",
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "- **伴生对象**\n",
    "- **密封类**\n",
    "- **委托与委托属性**\n",
    "- **协程**\n",
    "\n",
    "   一些 API 启动长时间运行的操作（例如网络 IO、文件 IO、CPU 或 GPU 密集型任务等），并要求调用者阻塞直到它们完成。协程提供了一种避免阻塞线程并用更廉价、更可控的操作替代线程阻塞的方法：协程挂起。\n",
    "\n",
    "协程通过将复杂性放入库来简化异步编程。程序的逻辑可以在协程中顺序地表达，而底层库会为我们解决其异步性。该库可以将用户代码的相关部分包装为回调、订阅相关事件、在不同线程（甚至不同机器！）上调度执行，而代码则保持如同顺序执行一样简单。\n",
    "\n",
    "#### 挂起函数\n",
    "\n",
    "  当我们调用标记有特殊修饰符 suspend 的函数时，会发生挂起\n",
    "  \n",
    " ```kotlin\n",
    "     suspend fun doSomething(foo: Foo): Bar {\n",
    "        ……\n",
    "    }\n",
    "\n",
    " ```\n",
    " \n",
    " 注意:**在 Kotlin 1.1+ 中协程是实验性的**\n",
    " \n",
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Kotlin 检索\n",
    "\n",
    "- Kotlin 官网  \n",
    "  http://kotlinlang.org/\n",
    "  \n",
    "- Kotlin 文档  \n",
    "   http://kotlinlang.org/docs/reference/\n",
    "   \n",
    "- Kotlin 官方博客  \n",
    "  https://blog.jetbrains.com/kotlin\n",
    "  \n",
    "- Kotlin 问题跟踪  \n",
    "  https://youtrack.jetbrains.com/issues/KT\n",
    "  \n",
    "- Kotlin 官方论坛  \n",
    "  https://discuss.kotlinlang.org/\n",
    "  \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "#  谢谢观赏"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
